UNPKG

@shinyongjun/react-datepicker

Version:
266 lines 10.2 kB
"use strict"; '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); }; Object.defineProperty(exports, "__esModule", { value: true }); var jsx_runtime_1 = require("react/jsx-runtime"); var react_1 = require("react"); var core_1 = require("../../constants/core"); var datetime_1 = require("../../utils/datetime"); var string_1 = require("../../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 = (0, react_1.useRef)(null); var nextRef = (0, react_1.useRef)(); var isValue = (0, react_1.useMemo)(function () { return core_1.VALUE_TYPES.includes(type); }, [type]); var isDisabled = (0, react_1.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 = (0, react_1.useMemo)(function () { switch (type) { case 'YYYY': case 'MM': case 'DD': return (0, datetime_1.getDateValueUnit)(dateValue, type); case 'hh': case 'mm': case 'ss': return (0, datetime_1.getTimeValueUnit)(timeValue, type); case ' ': return '&nbsp;'; default: return type; } }, [type, dateValue, timeValue]); var _b = (0, react_1.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 (!(0, string_1.isNumeric)(value)) { return setText(type); } var conditions = { YYYY: Number(value) > 9999 ? '9999' : value, MM: Number(value) > 12 ? '12' : (0, string_1.addLeadingZero)(value), DD: Number(value) > 31 ? '31' : (0, string_1.addLeadingZero)(value), hh: Number(value) > 23 ? '23' : (0, string_1.addLeadingZero)(value), mm: Number(value) > 59 ? '59' : (0, string_1.addLeadingZero)(value), ss: Number(value) > 59 ? '59' : (0, string_1.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); }; (0, react_1.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에 최종 저장 (0, react_1.useEffect)(function () { if (!(0, string_1.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에 저장. (0, react_1.useEffect)(function () { if (inputRef.current) { var nextSiblings = getNextSiblingsWithDataValueTrue(inputRef.current); if (nextSiblings.length) { nextRef.current = nextSiblings[0]; } } }, []); return ((0, jsx_runtime_1.jsx)("div", { role: "presentation", ref: inputRef, "data-value": isValue, className: "".concat(core_1.NAME_SPACE, "__input-unit"), dangerouslySetInnerHTML: { __html: text }, contentEditable: isValue && !disabled, suppressContentEditableWarning: true, onFocus: focusHandler, onClick: clickHandler, onInput: inputHandler, onKeyDown: numberChecker, onBlur: blurHandler, inputMode: "numeric" })); } exports.default = InputUnit; //# sourceMappingURL=InputUnit.js.map