UNPKG

@shinyongjun/react-datepicker

Version:
264 lines 9.94 kB
'use client'; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; import { jsx as _jsx } from "react/jsx-runtime"; import { useEffect, useMemo, useRef, useState, } from 'react'; import { NAME_SPACE, VALUE_TYPES } from '../../constants/core'; import { getDateValueUnit, getTimeValueUnit } from '../../utils/datetime'; import { addLeadingZero, isNumeric } from '../../utils/string'; // Function to select text function selectText(element) { var selection = window.getSelection(); var range = document.createRange(); range.selectNodeContents(element); if (selection) { selection.removeAllRanges(); selection.addRange(range); } } // 형제 Input Element중 NextInputElement를 검색. function getNextSiblingsWithDataValueTrue(currentElement) { var siblingElements = []; var nextSibling = currentElement.nextElementSibling; while (nextSibling) { if (nextSibling.dataset.value === 'true') { siblingElements.push(nextSibling); } nextSibling = nextSibling.nextElementSibling; } return siblingElements; } function InputUnit(_a) { var type = _a.type, dateValue = _a.dateValue, setDateValue = _a.setDateValue, onChange = _a.onChange, timeValue = _a.timeValue, setTimeValue = _a.setTimeValue, viewDate = _a.viewDate, setViewDate = _a.setViewDate, disabled = _a.disabled, isMounted = _a.isMounted, timePicker = _a.timePicker; var inputRef = useRef(null); var nextRef = useRef(); var isValue = useMemo(function () { return VALUE_TYPES.includes(type); }, [type]); var isDisabled = useMemo(function () { if (['hh', 'mm', 'ss'].includes(type)) { if (!timePicker) return true; if (type === 'hh' && !timePicker.hour) return true; if (type === 'mm' && !timePicker.minute) return true; if (type === 'ss' && !timePicker.second) return true; } return false; }, [type, timePicker]); var displayUnit = useMemo(function () { switch (type) { case 'YYYY': case 'MM': case 'DD': return getDateValueUnit(dateValue, type); case 'hh': case 'mm': case 'ss': return getTimeValueUnit(timeValue, type); case ' ': return '&nbsp;'; default: return type; } }, [type, dateValue, timeValue]); var _b = useState(displayUnit), text = _b[0], setText = _b[1]; var utilSetDateValue = function (_a) { var year = _a.year, month = _a.month, date = _a.date; setDateValue({ year: year !== null ? year : dateValue.year, month: month !== null ? month : dateValue.month, date: date !== null ? date : dateValue.date, }); }; var utilSetTimeValue = function (_a) { var hour = _a.hour, minute = _a.minute, second = _a.second; setTimeValue({ hour: hour !== null ? hour : timeValue.hour, minute: minute !== null ? minute : timeValue.minute, second: second !== null ? second : timeValue.second, }); }; // Input에서 Focus가 사라졌을 때 입력된 값을 타입에 맞게 value에 저장 var setValue = function (element) { var value = element.textContent || type; if (!isNumeric(value)) { return setText(type); } var conditions = { YYYY: Number(value) > 9999 ? '9999' : value, MM: Number(value) > 12 ? '12' : addLeadingZero(value), DD: Number(value) > 31 ? '31' : addLeadingZero(value), hh: Number(value) > 23 ? '23' : addLeadingZero(value), mm: Number(value) > 59 ? '59' : addLeadingZero(value), ss: Number(value) > 59 ? '59' : addLeadingZero(value), }; var processedValue = conditions[type] || value; if (text !== processedValue) { setText(processedValue); // element.innerText = processedValue; } }; var focusController = function () { var _a; if (nextRef.current) { nextRef.current.focus(); } else { (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.blur(); } }; // Type마다 특정 자리수 입력 시 다음 Input으로 focusing var inputHandler = function (e) { var _a, _b; var target = e.target; var count = ((_a = target.textContent) === null || _a === void 0 ? void 0 : _a.length) || 0; var value = Number(target.textContent); // 숫자 외 입력 방어 코드 if ((_b = target.textContent) === null || _b === void 0 ? void 0 : _b.match(/[^0-9]/g)) { setText(type); target.innerText = type; selectText(target); return; } switch (type) { case 'YYYY': if (count >= 4) { focusController(); } return; case 'MM': if (value >= 2 || count >= 2) { focusController(); } return; case 'DD': if (value >= 4 || count >= 2) { focusController(); } return; case 'hh': if (value >= 3 || count >= 2) { focusController(); } return; case 'mm': if (value >= 6 || count >= 2) { focusController(); } return; case 'ss': if (value >= 6 || count >= 2) { focusController(); } return; default: return; } }; // 허용된 입력 외 prevent var numberChecker = function (e) { if (isDisabled) e.preventDefault(); var allowKeys = [ 'Backspace', 'ArrowLeft', 'ArrowRight', 'ArrowDown', 'ArrowUp', 'Tab', ]; if (!allowKeys.includes(e.key) && !(e.key >= '0' && e.key <= '9')) { e.preventDefault(); } }; var focusHandler = function (e) { if (disabled) return; setTimeout(function () { selectText(e.target); }, 10); }; var clickHandler = function (e) { if (disabled) return; if (!isValue) { if (nextRef.current) { nextRef.current.focus(); } } else { var target = e.target; selectText(target); } }; var blurHandler = function (e) { if (disabled) return; setValue(e.target); }; useEffect(function () { if (!isMounted) return; setText(displayUnit); if (dateValue.year !== null && dateValue.month !== null && dateValue.date !== null) { if (onChange) { onChange(new Date(dateValue.year, dateValue.month, dateValue.date, timeValue.hour, timeValue.minute, timeValue.second)); } } // eslint-disable-next-line react-hooks/exhaustive-deps }, [displayUnit]); // Text의 변화를 감지하여 Value에 최종 저장 useEffect(function () { if (!isNumeric(text)) return; switch (type) { case 'YYYY': utilSetDateValue(__assign(__assign({}, dateValue), { year: Number(text) })); setViewDate("".concat(text, "-").concat(viewDate.split('-')[1], "-").concat(viewDate.split('-')[2])); return; case 'MM': utilSetDateValue(__assign(__assign({}, dateValue), { month: Number(text) - 1 })); setViewDate("".concat(viewDate.split('-')[0], "-").concat(text, "-").concat(viewDate.split('-')[2])); return; case 'DD': utilSetDateValue(__assign(__assign({}, dateValue), { date: Number(text) })); return; case 'hh': utilSetTimeValue(__assign(__assign({}, timeValue), { hour: Number(text) })); return; case 'mm': utilSetTimeValue(__assign(__assign({}, timeValue), { minute: Number(text) })); return; case 'ss': utilSetTimeValue(__assign(__assign({}, timeValue), { second: Number(text) })); return; default: return; } // eslint-disable-next-line react-hooks/exhaustive-deps }, [text]); // 다음 Input Unit을 nextRef에 저장. useEffect(function () { if (inputRef.current) { var nextSiblings = getNextSiblingsWithDataValueTrue(inputRef.current); if (nextSiblings.length) { nextRef.current = nextSiblings[0]; } } }, []); return (_jsx("div", { role: "presentation", ref: inputRef, "data-value": isValue, className: "".concat(NAME_SPACE, "__input-unit"), dangerouslySetInnerHTML: { __html: text }, contentEditable: isValue && !disabled, suppressContentEditableWarning: true, onFocus: focusHandler, onClick: clickHandler, onInput: inputHandler, onKeyDown: numberChecker, onBlur: blurHandler, inputMode: "numeric" })); } export default InputUnit; //# sourceMappingURL=InputUnit.js.map