phone-mask-uz
Version:
A flexible React component for formatting and validating Uzbekistan phone numbers
68 lines (67 loc) • 3.74 kB
JavaScript
import { __assign, __rest } from "tslib";
import React, { useState, useRef, useCallback, useEffect, forwardRef, } from "react";
import { normalizePhoneNumber } from "./normalizePhoneNumber";
export var PhoneInput = forwardRef(function (_a, ref) {
var _b = _a.value, value = _b === void 0 ? "" : _b, onChange = _a.onChange, error = _a.error, _c = _a.showError, showError = _c === void 0 ? true : _c, _d = _a.className, className = _d === void 0 ? "" : _d, _e = _a.disabled, disabled = _e === void 0 ? false : _e, InputComponent = _a.inputComponent, _f = _a.inputProps, inputProps = _f === void 0 ? {} : _f, WrapperComponent = _a.wrapperComponent, _g = _a.wrapperProps, wrapperProps = _g === void 0 ? {} : _g, _h = _a.placeholder, placeholder = _h === void 0 ? "+998 __ ___ __ __" : _h, props = __rest(_a, ["value", "onChange", "error", "showError", "className", "disabled", "inputComponent", "inputProps", "wrapperComponent", "wrapperProps", "placeholder"]);
var innerRef = useRef(null);
var _j = useState(normalizePhoneNumber(value)), inputValue = _j[0], setInputValue = _j[1];
var _k = useState(false), isFocused = _k[0], setIsFocused = _k[1];
var _l = useState(true), isValid = _l[0], setIsValid = _l[1];
var validatePhoneNumber = function (phone) {
var cleanNumber = phone.replace(/\D/g, "");
return cleanNumber.length === 12 && cleanNumber.startsWith("998");
};
useEffect(function () {
var normalizedValue = normalizePhoneNumber(value);
setInputValue(normalizedValue);
setIsValid(validatePhoneNumber(normalizedValue));
}, [value]);
var handleInputChange = useCallback(function (e) {
var rawValue = e.target.value;
if (!rawValue.startsWith("+998")) {
return;
}
var formattedValue = normalizePhoneNumber(rawValue);
var valid = validatePhoneNumber(formattedValue);
setInputValue(formattedValue);
setIsValid(valid);
if (onChange) {
onChange(formattedValue, valid);
}
}, [onChange]);
var handleFocus = function () {
setIsFocused(true);
if (!inputValue || inputValue === "+998") {
setInputValue("+998");
if (onChange) {
onChange("+998", false);
}
}
};
var handleBlur = function () {
setIsFocused(false);
if (inputValue === "+998") {
setInputValue("");
if (onChange) {
onChange("", false);
}
}
};
var getInputClassName = useCallback(function () {
var classes = ["phone-input"];
if (className)
classes.push(className);
if (isFocused)
classes.push("focused");
if (!isValid && showError)
classes.push("error");
return classes.join(" ");
}, [className, isFocused, isValid, showError]);
var inputElement = InputComponent ? (React.createElement(InputComponent, __assign({ ref: ref || innerRef, value: inputValue, onChange: handleInputChange, onFocus: handleFocus, onBlur: handleBlur, disabled: disabled, className: getInputClassName(), placeholder: placeholder }, inputProps, props))) : (React.createElement("input", __assign({ ref: ref || innerRef, type: "tel", value: inputValue, onChange: handleInputChange, onFocus: handleFocus, onBlur: handleBlur, disabled: disabled, placeholder: placeholder, className: getInputClassName() }, props)));
if (WrapperComponent) {
return (React.createElement(WrapperComponent, __assign({}, wrapperProps, { error: showError ? error : undefined }), inputElement));
}
return inputElement;
});
PhoneInput.displayName = "PhoneInput";
export default PhoneInput;