@s-ui/react-molecule-phone-input
Version:
> Custom input component to handle phone validation. Gives the user a prefix selector and a phone number input. It also handles the phone number validation and the prefix selection.
174 lines (173 loc) • 7.58 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
var _excluded = ["autoHideHelpText", "disabled", "dropdownCloseIcon", "dropdownIcon", "hasError", "helpText", "id", "label", "name", "onChange", "onPrefixChange", "placeholder", "prefixes", "rightIcon", "initialSelectedPrefix", "setFormattedValue", "successText", "type", "value", "visiblePrefixes"];
import { useEffect, useRef, useState } from 'react';
import cx from 'classnames';
import PropTypes from 'prop-types';
import { inputSizes, inputTypes } from '@s-ui/react-atom-input';
import MoleculeDropdownList, { moleculeDropdownListDesigns } from '@s-ui/react-molecule-dropdown-list';
import MoleculeDropdownOption from '@s-ui/react-molecule-dropdown-option';
import MoleculeInputField from '@s-ui/react-molecule-input-field';
import { FLAG_SIZE, phoneValidationType } from './settings.js';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
var BASE_CLASS = 'sui-MoleculePhoneInput';
var NOOP = function NOOP() {};
export { PREFIXES } from './settings.js';
export default function MoleculePhoneInput(_ref) {
var _cx;
var _ref$autoHideHelpText = _ref.autoHideHelpText,
autoHideHelpText = _ref$autoHideHelpText === void 0 ? false : _ref$autoHideHelpText,
disabled = _ref.disabled,
dropdownCloseIcon = _ref.dropdownCloseIcon,
dropdownIcon = _ref.dropdownIcon,
hasError = _ref.hasError,
helpText = _ref.helpText,
id = _ref.id,
label = _ref.label,
name = _ref.name,
onChange = _ref.onChange,
_ref$onPrefixChange = _ref.onPrefixChange,
onPrefixChange = _ref$onPrefixChange === void 0 ? NOOP : _ref$onPrefixChange,
placeholder = _ref.placeholder,
_ref$prefixes = _ref.prefixes,
prefixes = _ref$prefixes === void 0 ? [] : _ref$prefixes,
rightIcon = _ref.rightIcon,
_ref$initialSelectedP = _ref.initialSelectedPrefix,
initialSelectedPrefix = _ref$initialSelectedP === void 0 ? prefixes[0] : _ref$initialSelectedP,
setFormattedValue = _ref.setFormattedValue,
successText = _ref.successText,
_ref$type = _ref.type,
type = _ref$type === void 0 ? phoneValidationType.DEFAULT : _ref$type,
_ref$value = _ref.value,
value = _ref$value === void 0 ? '' : _ref$value,
_ref$visiblePrefixes = _ref.visiblePrefixes,
visiblePrefixesProp = _ref$visiblePrefixes === void 0 ? true : _ref$visiblePrefixes,
props = _objectWithoutPropertiesLoose(_ref, _excluded);
var _useState = useState(false),
showDropdown = _useState[0],
setShowDropdown = _useState[1];
var _useState2 = useState(initialSelectedPrefix),
selectedPrefix = _useState2[0],
setSelectedPrefix = _useState2[1];
var _useState3 = useState(false),
isLandLine = _useState3[0],
setIsLandLine = _useState3[1];
var modalRef = useRef(null);
var inputPrefixRef = useRef(null);
var inputMask = selectedPrefix && {
mask: isLandLine ? selectedPrefix.mask.landlineMask : selectedPrefix.mask.mobileMask
};
var visiblePrefixes = visiblePrefixesProp && prefixes.length > 1;
var baseClass = cx((_cx = {
disabled: disabled,
splitted: type === phoneValidationType.SPLITTED
}, _cx[BASE_CLASS + "--error"] = hasError, _cx.withLabel = !!label, _cx), BASE_CLASS);
// Close dropdown when click outside
useEffect(function () {
var handleClickOutside = function handleClickOutside(event) {
if (modalRef.current && !modalRef.current.contains(event.target) && !inputPrefixRef.current.contains(event.target)) {
setShowDropdown(false);
}
};
document.addEventListener('mousedown', handleClickOutside);
return function () {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);
useEffect(function () {
onPrefixChange(selectedPrefix);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedPrefix]);
var handlePhoneChange = function handlePhoneChange(e, _ref2) {
var value = _ref2.value;
setIsLandLine(selectedPrefix.landlinePrefixs.includes(value[0]));
typeof setFormattedValue === 'function' && setFormattedValue(value);
typeof onChange === 'function' && onChange(e, {
name: name != null ? name : id,
prefix: selectedPrefix.countryCode,
value: value.toString().replace(/\s/g, ''),
// remove spaces from value
isLandLine: isLandLine
});
};
return /*#__PURE__*/_jsxs("div", {
className: baseClass,
children: [/*#__PURE__*/_jsxs("div", {
className: baseClass + "-input",
children: [/*#__PURE__*/_jsxs("div", {
ref: inputPrefixRef,
className: baseClass + "-input-prefix",
onClick: function onClick() {
return !disabled && setShowDropdown(!showDropdown);
},
children: [selectedPrefix && /*#__PURE__*/_jsx("img", {
height: FLAG_SIZE,
width: FLAG_SIZE,
className: baseClass + "-input-prefix-flag",
src: selectedPrefix == null ? void 0 : selectedPrefix.flag
}), visiblePrefixes && (showDropdown ? dropdownCloseIcon : dropdownIcon)]
}), /*#__PURE__*/_jsxs("div", {
className: baseClass + "-input-phoneContainer",
children: [selectedPrefix && /*#__PURE__*/_jsx("p", {
className: baseClass + "-input-prefix-code",
children: selectedPrefix.countryCode
}), /*#__PURE__*/_jsx(MoleculeInputField, _extends({}, _extends({}, props, {
autoHideHelpText: autoHideHelpText,
id: id,
label: label,
name: name,
placeholder: placeholder,
successText: successText
}), hasError ? {
errorText: helpText
} : {
helpText: helpText
}, {
disabled: disabled,
mask: inputMask,
noBorder: true,
onChange: handlePhoneChange,
size: inputSizes.SMALL,
type: inputTypes.MASK,
value: value.toString()
})), rightIcon && /*#__PURE__*/_jsx("div", {
className: baseClass + "-input-icon",
children: rightIcon
})]
})]
}), showDropdown && visiblePrefixes && /*#__PURE__*/_jsx("div", {
className: baseClass + "-dropdown",
children: /*#__PURE__*/_jsx(MoleculeDropdownList, {
design: moleculeDropdownListDesigns.FLAT,
ref: modalRef,
visible: visiblePrefixes,
children: prefixes.map(function (prefix) {
return /*#__PURE__*/_jsx(MoleculeDropdownOption, {
value: prefix.value,
selected: selectedPrefix.value === prefix.value,
onClick: function onClick() {
setSelectedPrefix(prefix);
setShowDropdown(false);
},
children: /*#__PURE__*/_jsxs("div", {
className: baseClass + "-dropdown-option",
children: [/*#__PURE__*/_jsx("img", {
height: FLAG_SIZE,
width: FLAG_SIZE,
className: baseClass + "-dropdown-option-label",
src: prefix.flag
}), /*#__PURE__*/_jsx("span", {
className: baseClass + "-dropdown-option-label",
children: prefix.label
}), /*#__PURE__*/_jsxs("span", {
className: baseClass + "-dropdown-option-code",
children: ["(", prefix.countryCode, ")"]
})]
})
}, prefix.countryCode);
})
})
})]
});
}
MoleculePhoneInput.displayName = 'MoleculePhoneInput';