UNPKG

@activecollab/components

Version:

ActiveCollab Components

218 lines • 7.96 kB
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