UNPKG

@harvest-profit/npk

Version:
127 lines 5.59 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const useMask_1 = __importDefault(require("../hooks/useMask")); const masks_1 = require("../Input/masks"); // Handles the individual segments of the date/time input const InputSegment = ({ segment, ...props }) => { let mask = null; let placeholder = ''; switch (segment) { case 'year': mask = masks_1.calendarYearMask; placeholder = 'yyyy'; break; case 'month': mask = masks_1.calendarMonthMask; placeholder = 'mm'; break; case 'monthName': mask = masks_1.calendarMonthNameMask; placeholder = 'mmm'; break; case 'day': mask = masks_1.calendarDayMask; placeholder = 'dd'; break; case 'hour': mask = masks_1.calendarHourMask; placeholder = '––'; break; case 'minute': mask = masks_1.calendarMinuteMask; placeholder = '––'; break; case 'TOD': mask = masks_1.calendarTimeOfDayMask; placeholder = 'AM'; break; } const formatValue = (inputValue) => { if (inputValue === '0') return ''; return mask(props).formatter(`${inputValue || ''}`); }; const [value, setValue] = (0, react_1.useState)(formatValue(props.value) || ''); const validatingValueRef = (0, react_1.useRef)(value); const [isFocused, setIsFocused] = (0, react_1.useState)(false); const inputMask = (0, useMask_1.default)({ ...props, mask: mask(props), // Since we are using a span[contentEditable] as the input, we need to use the valueRef to get the current value instead of relying on event.target.value. valueRef: validatingValueRef, navigateWithArrows: true, // On top of input validation, we also need to process the key strokes to update the value since we are using a span[contentEditable] as the input. // This allows us to autocomplete certain values (e.g. a = AM, p = PM) and also handle backspace/delete. onKeyDown: (e, specialKey) => { let newValue = validatingValueRef.current; if (!specialKey) { newValue = newValue + e.key; } else if (e.key === 'Backspace' || e.key === 'Delete') { if (segment === 'TOD') newValue = ''; newValue = newValue.slice(0, newValue.length - 1); } else { if (e.key !== 'Tab') e.preventDefault(); return; } if (segment === 'TOD') { setValue((0, masks_1.calendarTimeOfDayMask)().autoComplete(newValue, e.key)); } else if (segment === 'monthName') { setValue((0, masks_1.calendarMonthNameMask)().autoComplete(newValue, e.key)); } else { setValue(newValue); } e.preventDefault(); } }); (0, react_1.useEffect)(() => { // if the value is a complete value (2 digits for month, day, hour, minute, 4 digits for year) // We want to set the validatingValueRef to an empty string so that when the input is focused again, // the user can type in a complete new value instead of having to delete the old value if (['month', 'day', 'hour', 'minute'].includes(segment) && value.length === 2) { validatingValueRef.current = ''; } else if (['year'].includes(segment) && value.length === 4) { validatingValueRef.current = ''; } else if (['monthName'].includes(segment) && value.length >= 3) { validatingValueRef.current = ''; } else { validatingValueRef.current = value; } // Publish the change to the parent component if the value is different if (props.onChange && formatValue(props.value) !== formatValue(value)) props.onChange(value); }, [value]); (0, react_1.useEffect)(() => { if (!isFocused && formatValue(props.value) !== formatValue(value)) setValue(formatValue(props.value)); }, [props.value]); const onBlur = (e) => { setIsFocused(false); if (props.setIsFocused) props.setIsFocused(false); setValue(inputMask.formatter(value)); }; const onFocus = (e) => { setIsFocused(true); if (props.setIsFocused) props.setIsFocused(true); }; // Use a placeholder if the value is empty const valueIsEmpty = value === '' || value === undefined || value === null; return ((0, jsx_runtime_1.jsx)("span", { tabIndex: 0, "data-component": "input-segment", onKeyDown: inputMask.onKeyDown, onClick: e => e.preventDefault(), onBlur: onBlur, onFocus: onFocus, enterKeyHint: "next", inputMode: "numeric", contentEditable: true, suppressContentEditableWarning: true, role: "spinbutton", style: { minWidth: segment === 'year' ? '2.35em' : '1.35em', caretColor: 'transparent' }, "data-placeholder": valueIsEmpty, children: valueIsEmpty ? placeholder : value })); }; exports.default = InputSegment; //# sourceMappingURL=InputSegment.js.map