@activecollab/components
Version:
ActiveCollab Components
218 lines • 7.96 kB
JavaScript
import { useCallback, useMemo, useRef, useState } from "react";
import { formatHours } from "../utils";
import { validateTimeInput } from "../utils";
export const useInputHours = (_ref, inputRef) => {
let {
value,
withLeadingZero,
onSave,
validation = validateTimeInput,
allowEmptyValue,
onCancel,
minuteIncrement = 1,
incrementOnlySelected,
onEnterKeyPress,
onChange,
onClick
} = _ref;
const [currentValue, setCurrentValue] = useState(() => formatHours(value, withLeadingZero));
const [prevValue, setPrevValue] = useState(() => formatHours(value, withLeadingZero));
const escapeRef = useRef(false);
const handleBlur = useCallback(e => {
if (escapeRef.current) {
setCurrentValue(prevValue);
} else {
if (e.target.value.trim().length > 0 && prevValue !== e.target.value) {
const _value = formatHours(e.target.value, withLeadingZero);
setPrevValue(_value);
setCurrentValue(_value);
typeof onSave === "function" && onSave(e);
} else {
if (!allowEmptyValue) {
setCurrentValue(prevValue);
typeof onCancel === "function" && onCancel(e);
} else {
if (typeof onSave === "function" && prevValue !== e.target.value) {
onSave(e);
} else {
typeof onCancel === "function" && onCancel(e);
}
}
}
}
}, [allowEmptyValue, onCancel, onSave, prevValue, withLeadingZero]);
const handleIncrementDecrement = useCallback(increment => {
if (inputRef.current) {
const selectionStart = inputRef.current.selectionStart;
if (selectionStart !== null) {
const dotsIndex = currentValue.indexOf(":");
const [hours, minutes] = currentValue.split(":").map(Number);
let newHours = hours;
let newMinutes = minutes;
if (selectionStart < dotsIndex) {
if (increment) {
newHours += 1;
} else {
newHours -= 1;
if (newHours < 0) newHours = 0;
}
} else if (selectionStart > dotsIndex) {
if (increment) {
newMinutes += minuteIncrement;
if (newMinutes > 59) {
newMinutes = 0;
if (!incrementOnlySelected) newHours += 1;
}
} else {
if (newMinutes >= minuteIncrement || newMinutes === 0) {
newMinutes -= minuteIncrement;
if (newMinutes < 0 && newHours > 0) {
newMinutes = 60 - minuteIncrement;
if (!incrementOnlySelected) newHours -= 1;
}
if (newHours < 0) {
newHours = 0;
}
} else {
newMinutes = 0;
}
}
}
const newMinutesString = newMinutes < 10 ? "0" + newMinutes : newMinutes;
const newHoursString = withLeadingZero && newHours < 10 ? "0" + newHours : newHours;
const newValue = newHoursString + ":" + newMinutesString;
if (validation(newValue, withLeadingZero)) {
setCurrentValue(newValue);
if (onChange) onChange(newValue);
requestAnimationFrame(() => {
var _inputRef$current;
const newDotsIndex = newValue.indexOf(":");
const isHoursSelected = selectionStart < newDotsIndex;
const newSelectionStart = isHoursSelected ? 0 : newDotsIndex + 1;
const selectionEnd = isHoursSelected ? newDotsIndex : newValue.length;
(_inputRef$current = inputRef.current) == null || _inputRef$current.setSelectionRange(newSelectionStart, selectionEnd);
});
}
}
}
}, [currentValue, incrementOnlySelected, inputRef, minuteIncrement, onChange, validation, withLeadingZero]);
const handleKeyDown = useCallback(e => {
if (e.key === "Enter") {
e.target.blur();
if (typeof onEnterKeyPress === "function") onEnterKeyPress(e.target.value);
}
if (e.key === "ArrowLeft") {
return;
}
if (e.key === "ArrowRight") {
return;
}
if (e.key === "Escape") {
escapeRef.current = true;
e.target.blur();
typeof onCancel === "function" && onCancel(e);
escapeRef.current = false;
}
if (e.key === "Backspace") {
return;
}
if (e.key === "Delete") {
return;
}
if ((e.metaKey || e.ctrlKey) && e.key === "a") {
var _inputRef$current2;
(_inputRef$current2 = inputRef.current) == null || _inputRef$current2.select();
return;
}
const input = e.target;
const start = input.selectionStart;
const end = input.selectionEnd;
const currentValue = input.value;
if (e.key === "Tab") {
if (start !== end) {
if (e.shiftKey) {
const newDotsIndex = currentValue.indexOf(":");
const isMinutesSelected = start > newDotsIndex;
if (isMinutesSelected) {
var _inputRef$current3;
e.preventDefault();
(_inputRef$current3 = inputRef.current) == null || _inputRef$current3.setSelectionRange(0, newDotsIndex);
}
} else {
const newDotsIndex = currentValue.indexOf(":");
const isHoursSelected = start < newDotsIndex;
if (isHoursSelected) {
var _inputRef$current4;
e.preventDefault();
(_inputRef$current4 = inputRef.current) == null || _inputRef$current4.setSelectionRange(newDotsIndex + 1, currentValue.length);
}
}
}
return;
}
if (start !== end) {
if (e.key === "ArrowUp") {
handleIncrementDecrement(true);
return;
}
if (e.key === "ArrowDown") {
handleIncrementDecrement(false);
return;
}
const newValue = currentValue.substring(0, start) + e.key + currentValue.substring(end);
if (!validation(newValue, withLeadingZero)) {
e.preventDefault();
return;
}
} else {
const newValue = currentValue.substring(0, start) + e.key + currentValue.substring(end);
if (!validation(newValue, withLeadingZero)) {
e.preventDefault();
return;
}
}
}, [handleIncrementDecrement, inputRef, onCancel, onEnterKeyPress, validation, withLeadingZero]);
const handleChange = useCallback(e => {
setCurrentValue(e.target.value);
if (onChange) onChange(e.target.value);
}, [onChange]);
const handleClick = useCallback(e => {
var _inputRef$current5;
const selectionStart = (_inputRef$current5 = inputRef.current) == null ? void 0 : _inputRef$current5.selectionStart;
if (inputRef.current && currentValue && currentValue.length > 0 && typeof selectionStart === "number") {
const dotsIndex = currentValue.indexOf(":");
if (selectionStart < dotsIndex) {
var _inputRef$current6;
(_inputRef$current6 = inputRef.current) == null || _inputRef$current6.setSelectionRange(0, dotsIndex);
} else if (selectionStart >= dotsIndex) {
var _inputRef$current7;
(_inputRef$current7 = inputRef.current) == null || _inputRef$current7.setSelectionRange(dotsIndex + 1, currentValue.length);
}
}
if (typeof onClick === "function") {
onClick(e);
}
}, [currentValue, inputRef, onClick]);
const handleDoubleClick = useCallback(() => {
if (inputRef.current) {
var _inputRef$current8;
(_inputRef$current8 = inputRef.current) == null || _inputRef$current8.select();
}
}, [inputRef]);
const inputProps = useMemo(() => {
return {
value: currentValue,
onBlur: handleBlur,
onKeyDown: handleKeyDown,
onChange: handleChange,
onClick: handleClick,
onDoubleClick: handleDoubleClick
};
}, [currentValue, handleBlur, handleChange, handleClick, handleDoubleClick, handleKeyDown]);
return {
inputProps,
setCurrentValue,
setPrevValue
};
};
//# sourceMappingURL=useInputHours.js.map